package models

import (
	"context"
	"fmt"
	"gameserver/event"
	"gameserver/tools/TestRobot/cmd"
	"sync/atomic"
	"time"

	"gitee.com/night-tc/gobige/common"
	"gitee.com/night-tc/gobige/entity"
	"gitee.com/night-tc/gobige/logger"
	"gitee.com/night-tc/gobige/msgdef/protomsg"
	"gitee.com/night-tc/gobige/threads"
	"gitee.com/night-tc/gobige/timerwheel"
)

type RobotUser struct {
	entity.DelayCallHost
	/* 指令部分 */
	Input atomic.Value //输入指令
	Logic IUserLogic   //运行的逻辑

	/* 数据 */
	UserName string //账号名
	Channel  string //
	UserID   uint64 //账号ID
	GroupID  uint64 //小区服ID
	RoleName string //角色名字
	RolePID  uint64 //角色名字
	EntityID uint64 //实例ID

	/* 登录有关 */
	Verify      *protomsg.ClientVerifyReq //Gateway的验证信息
	GatewayAddr string                    //数据地址
	Gateway     *RobotSession             //数据连接

	/* 管理器 */
	thgo     threads.SubThreadGo //协程管理器
	timer    *timerwheel.Timer   //主角 定时器
	eventMgr *event.EventMgr     //事件管理器

	/* 测试有关记录 */

	NoteStauts    string    // 描述状态
	GameTimeStart time.Time // 游戏开始时间
	ReqStartTime  int64     //用于统计消息回复时间用
}

func NewRobotUser() *RobotUser {
	user := new(RobotUser)
	user.Input.Store(cmd.NilCmd)
	user.timer = timerwheel.NewTimer()
	user.eventMgr = event.NewEventMgr()
	user.GameTimeStart = time.Now()
	user.ReqStartTime = 0
	return user
}

func (this *RobotUser) Start(thgo *threads.ThreadGo) {
	this.thgo = *threads.NewSubThreadGo(thgo)
	this.timer.Start()
	this.eventMgr.Prepare()
	this.thgo.Go(this.handle)
}

func (this *RobotUser) Stop() {
	GetRobotMgr().caluserch <- this.UserID
	GetRobotMgr().SetNoteStatus(this.UserID, "")
	this.thgo.Cal()
}

func (this *RobotUser) handle(ctx context.Context) {
	this.GameTimeStart = time.Now()
	defer func() {
		this.Stop()
		if this.Gateway != nil {
			this.Gateway.Close()
		}
	}()
	var msgchan chan bool
	tk := time.NewTicker(33 * time.Millisecond)
	defer tk.Stop()

	for {
		select {
		case <-ctx.Done():
			return
		// case <-this.StatusPl.C:
		// 	if this.Logic != nil {
		// 		logger.Infof("User:%s logic:%s", this.UserName, this.Logic)
		// 	}
		case <-msgchan:
			this.loopMsg()
		case nw := <-tk.C:
			if this.Gateway != nil {
				msgchan = this.Gateway.MsgHander.GetCallChan()
			}
			this.loop(nw)
		}
	}
}

func (this *RobotUser) loop(nw time.Time) {
	defer func() {
		if err := recover(); err != nil {
			logger.Error("RobotUser handle panic :", err)
			buf := common.StackTrace()
			common.OnRecover(err, buf, this)

		}
	}()
	/*
	   1、有指令加载指令
	   2、运行Logic
	   3、运行行为树

	*/
	// if this.Gateway != nil {
	// 	this.Gateway.DoMsg()
	// }
	input := this.Input.Load().(*cmd.InputCmd)
	if input != nil {
		//有新的指令，所以运行新的指令
		this.Input.Store(cmd.NilCmd)
		this.ClearLogic()
		this.Logic = input.NewLogic().(IUserLogic)
		this.Logic.Init(this)
	} else {
		input = nil
	}
	if this.Logic != nil {
		if this.Logic.IsEnd() {
			this.ClearLogic()
		} else {
			this.Logic.Run()
		}
	}
	//bev
	// if this.Bev != nil {
	// 	this.Bev.Tick()
	// 	if s := this.Bev.PopStatus(); s != "" {
	// 		GetRobotMgr().SetNoteStatus(this.RolePID, s)
	// 	}
	// }
	this.timer.OnTick(nw)
}

func (this *RobotUser) loopMsg() {
	defer func() {
		if err := recover(); err != nil {
			logger.Error("RobotUser handle panic :", err)
			buf := common.StackTrace()
			common.OnRecover(err, buf, this)

		}
	}()
	if this.Gateway != nil {
		this.Gateway.MsgHander.DoMsg()
	}
}

//--------------------------------------------------------

// / 清除逻辑
func (user *RobotUser) ClearLogic() {
	if user.Logic != nil {
		user.Logic.Destroy()
	}
	user.Logic = nil
}

// String 返回用户信息
func (this *RobotUser) String() string {
	return fmt.Sprintf("RobotUser UserID:%d RoleName:%s RolePID:%d ",
		this.UserID, this.RoleName, this.RolePID)
}
